import 'dart:convert';
import 'package:crclib/catalog.dart';
import 'package:get/get.dart';
import 'package:stock_helper/core/network/socket_client.dart';
import '../../data/models/recent_closing_price_model.dart';
import '../../data/models/stock_basic_bean.dart';

import '../../data/models/bao_stock_record_bean.dart';


class BaoStockService extends GetxService {
  final SocketClient _socketClient = Get.find<SocketClient>();

  @override
  void onInit() {
    super.onInit();
  }

  /// 登录BaoStock
  Future<bool> login() async {
    try {
      final msgLogin =
          "00.8.90\u000100\u00010000000024login\u0001anonymous\u0001123456\u00010\u00013460013509";
      await _socketClient.sendMessageLogin(msgLogin);
      final response = await _socketClient.receiveMessageLogin();

      // 检查登录是否成功
      if (response.contains("success") || response.contains("登录成功")) {
        print("登录成功");
        return true;
      } else {
        print("登录失败: $response");
        return false;
      }
    } catch (e) {
      print("登录过程出错: $e");
      return false;
    }
  }

  /// 查询历史K线数据
  Future<List<RecentClosingPrice>> queryHistoryKData(
    String code,
    String startDate,
    String endDate, [
    String fields = "date,code,close",
    String frequency = "d",
    int adjustFlag = 3,
  ]) async {
    final result = <RecentClosingPrice>[];

    // 确保已登录
    final isLoggedIn = await login();
    if (!isLoggedIn) {
      print("无法登录Baostock");
      return result;
    }

    var msgBody =
        "query_history_k_data\u0001anonymous\u00011\u000110000\u0001$code\u0001$fields\u0001$startDate\u0001$endDate\u0001$frequency\u0001$adjustFlag";
    final toMessageHeader = _addZeroForString(msgBody.length, 10, true);
    var msgHeader = "00.8.90\u000111\u0001$toMessageHeader";

    final headBody = msgHeader + msgBody;
    final crc32str = Crc32().convert(utf8.encode(headBody));

    var sendData = headBody + "\u0001" + crc32str.toString();
    await _socketClient.sendMessage(sendData);
    final response = await _socketClient.receiveMessage2();

    if (response.isNotEmpty && response.endsWith("\n")) {
      final baoMsgList = response.split("\u0001");

      if (baoMsgList.length > 8) {
        final json = baoMsgList[8];
        try {
          // 清理JSON字符串
          final cleanedJson = _cleanJsonString(json);

          final allStockList = BaoStockRecordBean.fromJson(
            jsonDecode(cleanedJson),
          );

          for (var i = 0; i < allStockList.record.length; i++) {
            final date = allStockList.record[i][0];
            final stockCode = allStockList.record[i][1];
            final close = double.tryParse(allStockList.record[i][2]) ?? 0.0;

            result.add(
              RecentClosingPrice(date: date, code: stockCode, close: close),
            );
          }
        } catch (e) {
          print("查询历史K线数据json转换出错: ${e.toString()}");
          print("原始JSON字符串: $json");
        }
      }
    }
    // 按日期倒序排序（最近的日期在前）
    result.sort((a, b) => b.date.compareTo(a.date));

    return result;
  }
// 修改 bao_stock_service.dart 中的 getAllStocks 方法

  Future<List<String>> getAllStocks() async {
    final stockList = <String>[];

    // 确保已登录
    final isLoggedIn = await login();
    if (!isLoggedIn) {
      print("无法登录Baostock");
      return stockList;
    }

    const date = "2024-03-13";
    var msgBody = "query_all_stock\u0001anonymous\u00011\u000110000\u0001$date";
    final toMessageHeader = _addZeroForString(msgBody.length, 10, true);
    var msgHeader = "00.8.90\u000135\u0001$toMessageHeader";

    final headBody = msgHeader + msgBody;
    final crc32str = Crc32().convert(utf8.encode(headBody));

    var sendData = headBody + "\u0001" + crc32str.toString();
    await _socketClient.sendMessage(sendData);
    final allStocks = await _socketClient.receiveMessage2();

    if (allStocks.endsWith("TA[]]>\n")) {
      final baoMsgList = allStocks.split("\u0001");

      if (baoMsgList.length > 11) {
        final json = baoMsgList[8];
        try {
          // 清理JSON字符串，移除可能的非法字符
          final cleanedJson = _cleanJsonString(json);

          final allStockList = BaoStockRecordBean.fromJson(
            jsonDecode(cleanedJson),
          );

          // 修改股票代码过滤逻辑
          for (var item in allStockList.record) {
            final code = item[0];

            // 验证股票代码格式 - 放宽条件
            if (_isValidStockCode(code)) {
              stockList.add(code);
              print("添加股票代码: $code");
            } else {
              print("跳过无效代码: $code");
            }
          }
        } catch (e) {
          print("处理返回的所有股票数据json转换出错: ${e.toString()}");
          print("原始JSON字符串: $json");

          // 在手动解析中也添加验证
          _tryManualParse(allStocks, stockList);
        }
      }
    }

    print("总共获取到 ${stockList.length} 只股票");
    return stockList;
  }

// 修改股票代码验证方法，放宽条件
  bool _isValidStockCode(String code) {
    // 检查代码格式：sh.XXXXXX 或 sz.XXXXXX，其中X是数字
    // 允许的格式：
    // 上证A股: sh.60XXXX, sh.68XXXX (科创板)
    // 深证A股: sz.00XXXX, sz.30XXXX (创业板)
    final pattern = RegExp(r'^(sh\.(60)\d{4}|sz\.(00|30)\d{4})$');

    // 排除指数代码
    if (code.startsWith("sh.000") || code.startsWith("sz.399") || code.startsWith("sh.68")) {
      return false;
    }

    return pattern.hasMatch(code);
  }

// 修改手动解析方法，也添加验证
  void _tryManualParse(String response, List<String> stockList) {
    try {
      // 使用更精确的正则表达式匹配股票代码
      final pattern = RegExp(r'(sh\.(60|68)\d{4}|sz\.(00|30)\d{4})');
      final matches = pattern.allMatches(response);

      for (final match in matches) {
        final code = match.group(0);
        if (code != null && _isValidStockCode(code) && !stockList.contains(code)) {
          stockList.add(code);
          print("手动解析添加股票代码: $code");
        }
      }

      print("手动解析找到 ${stockList.length} 只股票");
    } catch (e) {
      print("手动解析失败: $e");
    }
  }

  /// 清理JSON字符串中的非法字符
  String _cleanJsonString(String json) {
    // 移除可能存在的控制字符
    String cleaned = json.replaceAll(RegExp(r'[\x00-\x1F\x7F]'), '');

    // 确保JSON以有效的结构开始和结束
    if (!cleaned.trim().startsWith('{') && !cleaned.trim().startsWith('[')) {
      // 尝试找到JSON的开始位置
      final startIndex = cleaned.indexOf('{');
      if (startIndex != -1) {
        cleaned = cleaned.substring(startIndex);
      } else {
        final startArrayIndex = cleaned.indexOf('[');
        if (startArrayIndex != -1) {
          cleaned = cleaned.substring(startArrayIndex);
        }
      }
    }

    // 确保JSON以有效的结构结束
    if (!cleaned.trim().endsWith('}') && !cleaned.trim().endsWith(']')) {
      // 尝试找到JSON的结束位置
      final endIndex = cleaned.lastIndexOf('}');
      if (endIndex != -1) {
        cleaned = cleaned.substring(0, endIndex + 1);
      } else {
        final endArrayIndex = cleaned.lastIndexOf(']');
        if (endArrayIndex != -1) {
          cleaned = cleaned.substring(0, endArrayIndex + 1);
        }
      }
    }

    return cleaned;
  }



  /// 查询股票基本信息
  Future<List<StockBasicBean>> getStockBasic(String code) async {
    final stockBasicBeanList = <StockBasicBean>[];

    // 确保已登录
    final isLoggedIn = await login();
    if (!isLoggedIn) {
      print("无法登录Baostock");
      return stockBasicBeanList;
    }

    var msgBody =
        "query_stock_basic\u0001anonymous\u00011\u000110000\u0001$code\u0001";
    final toMessageHeader = _addZeroForString(msgBody.length, 10, true);
    var msgHeader = "00.8.90\u000145\u0001$toMessageHeader";

    final headBody = msgHeader + msgBody;
    final crc32str = Crc32().convert(utf8.encode(headBody));

    var sendData = headBody + "\u0001" + crc32str.toString();
    await _socketClient.sendMessage(sendData);
    final stockBasic = await _socketClient.receiveMessage();

    if (stockBasic.endsWith("\n")) {
      final baoMsgList = stockBasic.split("\u0001");

      if (baoMsgList.length > 8) {
        final json = baoMsgList[8];
        try {
          // 清理JSON字符串
          final cleanedJson = _cleanJsonString(json);

          final allStockList = BaoStockRecordBean.fromJson(
            jsonDecode(cleanedJson),
          );

          for (var i = 0; i < allStockList.record.length; i++) {
            final code = allStockList.record[i][0];
            final codeName = allStockList.record[i][1];
            final ipoDate = allStockList.record[i][2];
            final outDate = allStockList.record[i][3];
            final type = allStockList.record[i][4];
            final status = int.tryParse(allStockList.record[i][5]) ?? 0;

            if (status == 1) {
              final stockBasicBean = StockBasicBean(
                code: code,
                codeName: codeName,
                ipoDate: ipoDate,
                isDelisted: false,
              );
              stockBasicBeanList.add(stockBasicBean);
            }
          }
        } catch (e) {
          print("查询股票基本信息json转换出错: ${e.toString()}");
          print("原始JSON字符串: $json");
        }
      }
    }
    return stockBasicBeanList;
  }

  // 在 BaoStockService 中添加重试机制
  Future<List<String>> getAllStocksWithRetry({int maxRetries = 3}) async {
    for (var i = 0; i < maxRetries; i++) {
      try {
        final result = await getAllStocks();
        if (result.isNotEmpty) {
          return result;
        }
        print('第 ${i + 1} 次尝试获取股票代码失败，准备重试...');
        await Future.delayed(Duration(seconds: 2));
      } catch (e) {
        print('第 ${i + 1} 次尝试获取股票代码异常: $e');
        if (i == maxRetries - 1) rethrow;
        await Future.delayed(Duration(seconds: 2));
      }
    }
    return [];
  }


  String _addZeroForString(int contents, int length, bool direction) {
    var content = contents.toString();
    var strLen = content.length;
    if (strLen < length) {
      while (strLen < length) {
        if (direction) {
          content = "0" + content;
        } else {
          content = content + "0";
        }
        strLen = content.length;
      }
    }
    return content;
  }
}
